home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
526-550
/
disk_527
/
toolmanager
/
source
/
ifficon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
7KB
|
225 lines
/*
* ifficon.c V1.4
*
* IFF brush handling
*
* (c) 1991 by Stefan Becker
*
*/
#include "ToolManager.h"
/* Our own DiskObject definition */
struct IFFDObj {
struct DiskObject id_dobj;
struct Image id_img;
ULONG id_size; /* size of image */
};
/* Bitmap header (BMHD) structure */
struct BitMapHeader {
UWORD w,h; /* Width, height in pixels */
WORD x,y;
UBYTE nplanes; /* Number of planes */
UBYTE Masking; /* Masking */
UBYTE Compression; /* Compression algorithm */
UBYTE pad1;
UWORD TransparentColor;
UBYTE XAspect,YAspect;
WORD PageWidth, PageHeight;
};
#define MSK_HASMASK 1
#define COMP_NO 0
#define COMP_BYTERUN1 1
#define BPR(w) ((((w)+15)>>4)<<1) /* Bytes per row formula */
/* IFF ID's */
#define ID_ILBM MAKE_ID('I','L','B','M')
#define ID_BMHD MAKE_ID('B','M','H','D')
#define ID_BODY MAKE_ID('B','O','D','Y')
/* miscellaneous */
struct Library *IFFParseBase;
/* Read BODY chunk into memory and convert it to an image */
static BOOL ReadBODY(struct IFFHandle *iff, struct BitMapHeader *bmhd,
UBYTE *dest, ULONG bpr, ULONG planeoff)
{
register UBYTE *sp,*dp;
register ULONG row;
UBYTE *src;
ULONG planes=bmhd->nplanes;
ULONG size=CurrentChunk(iff)->cn_Size;
BOOL ncomp=bmhd->Compression==COMP_NO;
BOOL mask=bmhd->Masking==MSK_HASMASK;
BOOL rc=TRUE;
/* Get memory for BODY chunk contents */
if (!(sp=src=malloc(size))) goto rbe1;
/* Read in the complete BODY chunk */
if (ReadChunkBytes(iff,src,size)!=size) goto rbe2;
for (row=0; row<bmhd->h; row++) /* Read data row by row */
{
register ULONG pl,rem;
register char k;
for (pl=0; pl<planes; pl++) /* Read data plane by plane */
{
dp=dest+pl*planeoff+row*bpr; /* Calculate destination pointer */
if (ncomp)
for (k=bpr; k--;) *dp++=*sp++; /* No compression */
else
{ /* Byte Run compression */
rem=bpr;
while (rem) /* Row not completed */
{
k=*sp++; /* Read compression code */
if (k>=0)
{ /* Literal copy */
if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
while (k--) *dp++=*sp++; /* Copy the following k+1 bytes */
}
else if (k!=-128) /* Code -128 == No Operation */
{ /* Byte run encoded */
register UBYTE byte;
k=-k;
if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
byte=*sp++; /* Get byte */
while (k--) *dp++=byte; /* Copy this byte -k+1 times */
}
}
}
}
if (mask) /* Skip mask plane */
if (ncomp)
sp+=bpr; /* No compression */
else
{ /* Byte Run compression */
rem=bpr;
while (rem) /* Row not completed */
{
k=*sp++; /* Read compression code */
if (k>=0)
{ /* Literal copy */
if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
sp+=k; /* Skip the following k+1 bytes */
}
else if (k!=-128) /* Code -128 == No Operation */
{ /* Byte run encoded */
k=-k;
if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
sp++; /* Skip this byte */
}
}
}
}
/* All OK */
rc=FALSE;
rbe2: free(src);
rbe1: return(rc);
}
/* Load an IFF brush and create a DiskObject */
struct DiskObject *LoadIFFIcon(char *name)
{
register struct IFFHandle *iff;
register struct IFFDObj *id=NULL;
struct ContextNode *cn;
struct StoredProperty *sp;
struct BitMapHeader *bmhd;
ULONG bpr,planeoff;
BOOL error=TRUE;
/* Open IFF parsing library */
if (!(IFFParseBase=OpenLibrary("iffparse.library",0))) goto lie1;
/* Get memory for DiskObject and clear it */
if (!(id=calloc(sizeof(struct IFFDObj),1))) goto lie2;
id->id_dobj.do_Version=WB_DISKVERSION;
id->id_dobj.do_Gadget.GadgetRender=&id->id_img;
id->id_dobj.do_Gadget.UserData=(APTR) WB_DISKREVISION;
/* Alloc IFF handle */
if (!(iff=AllocIFF())) goto lie3;
/* Open IFF file and init IFF handle */
if (!(iff->iff_Stream=Open(name,MODE_OLDFILE))) goto lie4;
InitIFFasDOS(iff);
/* Declare ILBM property & stop chunks. Open IFF context */
if (PropChunk(iff,ID_ILBM,ID_BMHD)) goto lie5;
if (StopChunk(iff,ID_ILBM,ID_BODY)) goto lie5;
if (StopOnExit(iff,ID_ILBM,ID_FORM)) goto lie5;
if (OpenIFF(iff,IFFF_READ)) goto lie5;
/* Start parsing */
if (ParseIFF(iff,IFFPARSE_STEP)) goto lie6;
/* Check for FORM ILBM chunk */
if (!(cn=CurrentChunk(iff))) goto lie6;
if ((cn->cn_ID!=ID_FORM) || (cn->cn_Type!=ID_ILBM)) goto lie6;
/* Continue parsing until BODY chunk is found */
if (ParseIFF(iff,IFFPARSE_SCAN)) goto lie6;
/* BMHD chunk found? */
if (!(sp=FindProp(iff,ID_ILBM,ID_BMHD))) goto lie6;
bmhd=(struct BitMapHeader *) sp->sp_Data;
/* Check compression type */
if ((bmhd->Compression!=COMP_NO) && (bmhd->Compression!=COMP_BYTERUN1))
goto lie6;
/* Retrieve BMHD chunk values */
id->id_dobj.do_Gadget.Width=bmhd->w;
id->id_dobj.do_Gadget.Height=bmhd->h+1;
id->id_img.Width=bmhd->w;
id->id_img.Height=bmhd->h;
id->id_img.Depth=bmhd->nplanes;
id->id_img.PlanePick=(1<<bmhd->nplanes)-1;
/* Allocate chip memory for image data */
bpr=BPR(bmhd->w); /* Bytes per row */
planeoff=bpr*bmhd->h; /* Bytes per plane */
id->id_size=planeoff*bmhd->nplanes; /* Bytes for image */
if (!(id->id_img.ImageData=AllocMem(id->id_size,
MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR)))
goto lie6;
/* Read ImageData */
error=ReadBODY(iff,bmhd,(UBYTE *) id->id_img.ImageData,bpr,planeoff);
if (error) FreeMem(id->id_img.ImageData,id->id_size);
lie6: CloseIFF(iff);
lie5: Close(iff->iff_Stream);
lie4: FreeIFF(iff);
lie3: if (error)
{
free(id);
id=NULL;
}
lie2: CloseLibrary(IFFParseBase);
lie1: return(id);
}
/* Free an IFF icon */
void FreeIFFIcon(struct DiskObject *dobj)
{
register struct IFFDObj *id=dobj;
FreeMem(id->id_img.ImageData,id->id_size);
free(id);
}